package cn.com.aiton.common.utils;

import cn.com.aiton.common.constant.Gbt209992007;
import cn.com.aiton.common.model.NodeDomain;
import cn.com.aiton.common.model.ServiceResult;
import cn.com.aiton.common.model.extend.AitonExtendGbtDirecDomain;
import cn.com.aiton.common.model.gbt209992007.*;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class Gbt209992007BytesToObjectUtils {
    private static final Logger LOG = LoggerFactory.getLogger(Gbt209992007BytesToObjectUtils.class);

    /**
     * 系统请求信号机方向与相位对应数据，信号机返回的是byte[]数组，
     * 需要通过此方法解析成对象列表
     *
     * @param bytes
     * @return
     */
    public static List<AitonExtendGbtDirecDomain> byte2Direc(byte[] bytes) {
        List<AitonExtendGbtDirecDomain> gbtDirecs = new ArrayList<>();
        byte[] objectArray = new byte[bytes[3] * Gbt209992007.PHASE_DIREC_BYTE_SIZE];
        System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
        byte[][] direcArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.PHASE_DIREC_RESULT_LEN, Gbt209992007.PHASE_DIREC_BYTE_SIZE);
        for (int i = 0; i < bytes[3]; i++) {
            AitonExtendGbtDirecDomain gbtDirec = new AitonExtendGbtDirecDomain();
            gbtDirec.setPhaseToDirecNumber(ByteUtils.bytesUInt(direcArrayResult[i][0]));
            gbtDirec.setPhaseNumber(ByteUtils.bytesUInt(direcArrayResult[i][1]));
            gbtDirec.setOverlapPhaseNumber(ByteUtils.bytesUInt(direcArrayResult[i][2]));
            gbtDirec.setRoadCount(ByteUtils.bytesUInt(direcArrayResult[i][3]));
            gbtDirec.setDirect(DirectIdToDirectUtil.getDirect((gbtDirec.getPhaseToDirecNumber().intValue())));
            gbtDirecs.add(gbtDirec);
        }
        return gbtDirecs;
    }

    /**
     * 设置方向与相位的数据 ，
     *
     * @param gbtDirecs 方向数据集合
     * @return
     */
    public static byte[] direc2Byte(List<AitonExtendGbtDirecDomain> gbtDirecs) {
        ServiceResult<Object> result = new ServiceResult<>();

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_PHASE_DIREC_RESPONSE, (byte) gbtDirecs.size());
        Iterator<AitonExtendGbtDirecDomain> gbtDirecIterator = gbtDirecs.iterator();
        while (gbtDirecIterator.hasNext()) {
            AitonExtendGbtDirecDomain gbtDirec = gbtDirecIterator.next();
            hex = ArrayUtils.add(hex, gbtDirec.getPhaseToDirecNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtDirec.getPhaseNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtDirec.getOverlapPhaseNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtDirec.getRoadCount().byteValue());
        }

        return hex;

    }

    /**
     * 向信号机发出通道请求后，返回的数据是byte[]数组。
     * 通过此方法，返回对象列表
     *
     * @param bytes
     * @return
     */
    public static List<GbtChannelDomain> byte2Channel(byte[] bytes) {
        List<GbtChannelDomain> gbtChannels = new ArrayList<>();
        byte[] objectArray = new byte[bytes[3] * Gbt209992007.CHANNEL_BYTE_SIZE];
        System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
        byte[][] channelArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.CHANNEL_RESULT_LEN, Gbt209992007.CHANNEL_BYTE_SIZE);
        for (int i = 0; i < bytes[3]; i++) {
            GbtChannelDomain gbtChannel = new GbtChannelDomain();
            gbtChannel.setChannelNumber(ByteUtils.bytesUInt(channelArrayResult[i][0]));
            gbtChannel.setControlSource(ByteUtils.bytesUInt(channelArrayResult[i][1]));
            gbtChannel.setAutoFlashControl(ByteUtils.bytesUInt(channelArrayResult[i][2]));
            gbtChannel.setControlType(ByteUtils.bytesUInt(channelArrayResult[i][3]));
            gbtChannels.add(gbtChannel);
        }
        return gbtChannels;
    }

    /**
     * 设置信号机的通道信息
     *
     * @param node
     * @param gbtChannels
     * @return
     */
    public static byte[] channel2Byte(NodeDomain node, List<GbtChannelDomain> gbtChannels) {

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_CHANNEL_RESPONSE, (byte) gbtChannels.size());
        Iterator<GbtChannelDomain> gbtChannelIterator = gbtChannels.iterator();
        while (gbtChannelIterator.hasNext()) {
            GbtChannelDomain gbtChannel = gbtChannelIterator.next();
            hex = ArrayUtils.add(hex, gbtChannel.getChannelNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtChannel.getControlSource().byteValue());
            hex = ArrayUtils.add(hex, gbtChannel.getAutoFlashControl().byteValue());
            hex = ArrayUtils.add(hex, gbtChannel.getControlType().byteValue());
        }

        return hex;
    }

    public static List<GbtOverlapPhaseDomain> byte2Overlap(byte[] bytes) {
        List<GbtOverlapPhaseDomain> gbtOverlaps = new ArrayList<>();
        byte[] objectArray = new byte[bytes[3] * Gbt209992007.OVERLAPPHASE_BYTE_SIZE];
        System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
        byte[][] overlapArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.OVERLAPPHASE_RESULT_LEN, Gbt209992007.OVERLAPPHASE_BYTE_SIZE);
        for (int i = 0; i < bytes[3]; i++) {
            GbtOverlapPhaseDomain gbtOverlap = new GbtOverlapPhaseDomain();
            gbtOverlap.setOverlapPhaseNumber(ByteUtils.bytesUInt(overlapArrayResult[i][0]));
            gbtOverlap.setOverlapPhaseType(ByteUtils.bytesUInt(overlapArrayResult[i][1]));
            gbtOverlap.setIncludePhaseCount(ByteUtils.bytesUInt(overlapArrayResult[i][2]));
            gbtOverlap.setIncludePhase(new String(overlapArrayResult[i][3] + "," + overlapArrayResult[i][4] + "," + overlapArrayResult[i][5] + "," + overlapArrayResult[i][6] + "," + overlapArrayResult[i][7] + "," + overlapArrayResult[i][8] + "," + overlapArrayResult[i][9] + "," + overlapArrayResult[i][10] + "," + overlapArrayResult[i][11] + "," + overlapArrayResult[i][12] + "," + overlapArrayResult[i][13] + "," + overlapArrayResult[i][14] + "," + overlapArrayResult[i][15] + "," + overlapArrayResult[i][16] + "," + overlapArrayResult[i][17] + "," + overlapArrayResult[i][18]));
            gbtOverlap.setAmendPhaseCount(ByteUtils.bytesUInt(overlapArrayResult[i][19]));
            gbtOverlap.setAmendPhase(new String(overlapArrayResult[i][20] + "," + overlapArrayResult[i][21] + "," + overlapArrayResult[i][22] + "," + overlapArrayResult[i][23] + "," + overlapArrayResult[i][24] + "," + overlapArrayResult[i][25] + "," + overlapArrayResult[i][26] + "," + overlapArrayResult[i][27] + "," + overlapArrayResult[i][28] + "," + overlapArrayResult[i][29] + "," + overlapArrayResult[i][30] + "," + overlapArrayResult[i][31] + "," + overlapArrayResult[i][32] + "," + overlapArrayResult[i][33] + "," + overlapArrayResult[i][34] + "," + overlapArrayResult[i][35]));
            gbtOverlap.setTailGreen(ByteUtils.bytesUInt(overlapArrayResult[i][36]));
            gbtOverlap.setTailYellow(ByteUtils.bytesUInt(overlapArrayResult[i][37]));
            gbtOverlap.setTailRed(ByteUtils.bytesUInt(overlapArrayResult[i][38]));
            gbtOverlaps.add(gbtOverlap);
        }
        return gbtOverlaps;
    }

    /**
     * 将跟随相位数据设置到信号机
     *
     * @param gbtOverlaps
     * @return
     */
    public static byte[] overlap2Byte(List<GbtOverlapPhaseDomain> gbtOverlaps) {

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_OVERLAPPHASE_RESPONSE, (byte) gbtOverlaps.size());
        Iterator<GbtOverlapPhaseDomain> gbtOverlapIterator = gbtOverlaps.iterator();
        while (gbtOverlapIterator.hasNext()) {
            GbtOverlapPhaseDomain gbtChannel = gbtOverlapIterator.next();
            hex = ArrayUtils.add(hex, gbtChannel.getOverlapPhaseNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtChannel.getOverlapPhaseType().byteValue());
            hex = ArrayUtils.add(hex, gbtChannel.getIncludePhaseCount().byteValue());
            hex = ArrayUtils.addAll(hex, OverlapPhaseUtils.stringToByteArray(gbtChannel.getIncludePhase()));
            hex = ArrayUtils.add(hex, gbtChannel.getAmendPhaseCount().byteValue());
            hex = ArrayUtils.addAll(hex, OverlapPhaseUtils.stringToByteArray(gbtChannel.getAmendPhase()));
            hex = ArrayUtils.add(hex, gbtChannel.getTailGreen().byteValue());
            hex = ArrayUtils.add(hex, gbtChannel.getTailYellow().byteValue());
            hex = ArrayUtils.add(hex, gbtChannel.getTailRed().byteValue());
        }

        return hex;
    }


    public static List<GbtPhaseDomain> byte2Phase(byte[] bytes) {
        List<GbtPhaseDomain> gbtPhases = new ArrayList<>();
        byte[] objectArray = new byte[bytes[3] * Gbt209992007.PHASE_BYTE_SIZE];
        System.arraycopy(bytes, 4, objectArray, 0, bytes[3] * Gbt209992007.PHASE_BYTE_SIZE);
        byte[][] phaseArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, bytes[3], Gbt209992007.PHASE_BYTE_SIZE);
        for (int i = 0; i < bytes[3]; i++) {
            GbtPhaseDomain gbtPhase = new GbtPhaseDomain();
            gbtPhase.setPhaseNumber(ByteUtils.bytesUInt(phaseArrayResult[i][0]));
            gbtPhase.setPedestrainGreen(ByteUtils.bytesUInt(phaseArrayResult[i][1]));
            gbtPhase.setPedestrainClear(ByteUtils.bytesUInt(phaseArrayResult[i][2]));
            gbtPhase.setMinGreen(ByteUtils.bytesUInt(phaseArrayResult[i][3]));
            gbtPhase.setGreenDelayUnit(ByteUtils.bytesUInt(phaseArrayResult[i][4]));
            gbtPhase.setMaxGreen1(ByteUtils.bytesUInt(phaseArrayResult[i][5]));
            gbtPhase.setMaxGreen2(ByteUtils.bytesUInt(phaseArrayResult[i][6]));
            gbtPhase.setFixGreen(ByteUtils.bytesUInt(phaseArrayResult[i][7]));
            gbtPhase.setGreenFlash(ByteUtils.bytesUInt(phaseArrayResult[i][8]));
            gbtPhase.setPhaseType(ByteUtils.bytesUInt(phaseArrayResult[i][9]));
            gbtPhase.setPhaseOption(ByteUtils.bytesUInt(phaseArrayResult[i][10]));
            gbtPhase.setExtend(ByteUtils.bytesUInt(phaseArrayResult[i][11]));
            gbtPhases.add(gbtPhase);
        }
        return gbtPhases;
    }

    /**
     * 设置信号机的相位参数，
     *
     * @param gbtPhases 相位模型对象的数组
     * @param gbtPhases
     * @return
     */
    public static byte[] phase2Byte(List<GbtPhaseDomain> gbtPhases) {

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_PHASE_RESPONSE, (byte) gbtPhases.size());
        Iterator<GbtPhaseDomain> gbtPhaseIterator = gbtPhases.iterator();
        while (gbtPhaseIterator.hasNext()) {
            GbtPhaseDomain gbtPhase = gbtPhaseIterator.next();
            byte[] objectArray = {gbtPhase.getPhaseNumber().byteValue(), gbtPhase.getPedestrainGreen().byteValue()
                    , gbtPhase.getPedestrainClear().byteValue(), gbtPhase.getMinGreen().byteValue()
                    , gbtPhase.getGreenDelayUnit().byteValue(), gbtPhase.getMaxGreen1().byteValue()
                    , gbtPhase.getMaxGreen2().byteValue(), gbtPhase.getFixGreen().byteValue()
                    , gbtPhase.getGreenFlash().byteValue(), gbtPhase.getPhaseType().byteValue()
                    , gbtPhase.getPhaseOption().byteValue(), gbtPhase.getExtend().byteValue()};
            hex = ArrayUtils.addAll(hex, objectArray);
        }
        return hex;

    }

    /**
     * 设置信号机的配时方案，此方法适用于32相位的第二代，三代信号机。
     *
     * @param node
     * @param byteString
     * @return
     */
    public static byte[] stageString2Byte(NodeDomain node, String byteString) {
        ServiceResult<String> message = new ServiceResult<>();

        byte[] hex = ByteUtils.hexStringToByte(byteString);
        return hex;

    }

    /**
     * 取得信号机的配时方案数据，此方法适用于32相位的第二代，三代信号机
     *
     * @param bytes
     * @return
     */
    public static String byteString2StageString(byte[] bytes) {
        ServiceResult<String> message = new ServiceResult<>();
        String str = ByteUtils.bytesToHexString(bytes);
        return str;

    }

    /**
     * 取得信号机的配时方案的集合，信号机第一代的16相位
     *
     * @param bytes
     * @return
     */
    public static List<GbtStagePatternDomain> byte2StageWith16Phase(byte[] bytes) {

        List<GbtStagePatternDomain> gbtStagePatterns = new ArrayList<>();
        int len = bytes[Gbt209992007.STAGE_RESULT_THIS_OFFSET_LEN];
        byte[] objectArray = new byte[len * Gbt209992007.STAGE_PATTERN_BYTE_SIZE_16];
        System.arraycopy(bytes, Gbt209992007.STAGE_RESULT_START_OFFSET_POSITION, objectArray, 0, objectArray.length);
        byte[][] stagePatternArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, len, Gbt209992007.STAGE_PATTERN_BYTE_SIZE_16);
        for (int i = 0; i < len; i++) {
            GbtStagePatternDomain gbtStagePattern = new GbtStagePatternDomain();
            gbtStagePattern.setStagePatternNumber(Integer.valueOf(stagePatternArrayResult[i][0]));
            gbtStagePattern.setStageNumber(Integer.valueOf(stagePatternArrayResult[i][1]));
            byte[] allowPhase = {stagePatternArrayResult[i][2], stagePatternArrayResult[i][3]};
            gbtStagePattern.setAllowPhase(ByteUtils.byteToInt(allowPhase));
            gbtStagePattern.setGreenTime((int) stagePatternArrayResult[i][4]);
            gbtStagePattern.setYellowTime((int) stagePatternArrayResult[i][5]);
            gbtStagePattern.setRedTime((int) stagePatternArrayResult[i][6]);
            gbtStagePattern.setOption((int) stagePatternArrayResult[i][7]);
            gbtStagePatterns.add(gbtStagePattern);
        }

        return gbtStagePatterns;


    }

    /**
     * 取得信号机的配时方案的集合，信号机第一代的16相位
     *   *  可以使用，不过要处理多于的字节数组
     * @param bytes
     * @return
     */
    @Deprecated
    public List<GbtStagePatternDomain> getStagePattern16Phase(byte[] bytes) {
        List<GbtStagePatternDomain> gbtStagePatterns = new ArrayList<>();

        byte[] objectArray = new byte[Gbt209992007.STAGE_RESULT_LEN * Gbt209992007.STAGEPATTERN_RESULT_LEN * Gbt209992007.STAGE_PATTERN_BYTE_SIZE_16];
        System.arraycopy(bytes, 5, objectArray, 0, objectArray.length);
        byte[][] stagePatternArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.STAGE_RESULT_LEN * Gbt209992007.STAGEPATTERN_RESULT_LEN, Gbt209992007.STAGE_PATTERN_BYTE_SIZE_16);
        for (int i = 0; i < Gbt209992007.STAGE_RESULT_LEN * Gbt209992007.STAGEPATTERN_RESULT_LEN; i++) {
            GbtStagePatternDomain gbtStagePattern = new GbtStagePatternDomain();
            gbtStagePattern.setStagePatternNumber(Integer.valueOf(stagePatternArrayResult[i][0]));
            gbtStagePattern.setStageNumber(Integer.valueOf(stagePatternArrayResult[i][1]));
            byte[] allowPhase = {stagePatternArrayResult[i][2], stagePatternArrayResult[i][3]};
            gbtStagePattern.setAllowPhase(ByteUtils.byteToInt(allowPhase));
            gbtStagePattern.setGreenTime((int) stagePatternArrayResult[i][4]);
            gbtStagePattern.setYellowTime((int) stagePatternArrayResult[i][5]);
            gbtStagePattern.setRedTime((int) stagePatternArrayResult[i][6]);
            gbtStagePattern.setOption((int) stagePatternArrayResult[i][7]);
            gbtStagePatterns.add(gbtStagePattern);
        }
        return gbtStagePatterns;
    }

    /**
     * 取得信号机的配时方案的集合，此方案适用于第二代，第三代信号机。32相位
     *  可以使用，不过要处理多于的字节数组
     * @param bytes
     * @return
     */
    @Deprecated
    public List<GbtStagePatternDomain> getStagePattern32Phase(byte[] bytes) {
        List<GbtStagePatternDomain> gbtStagePatterns = new ArrayList<GbtStagePatternDomain>();

        byte[] objectArray = new byte[Gbt209992007.STAGE_RESULT_LEN * Gbt209992007.STAGEPATTERN_RESULT_LEN * Gbt209992007.STAGEPATTERN_BYTE_SIZE];
        System.arraycopy(bytes, 5, objectArray, 0, (bytes.length - 5));
        byte[][] stagePatternArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.STAGE_RESULT_LEN * Gbt209992007.STAGEPATTERN_RESULT_LEN, Gbt209992007.STAGEPATTERN_BYTE_SIZE);
        for (int i = 0; i < Gbt209992007.STAGE_RESULT_LEN * Gbt209992007.STAGEPATTERN_RESULT_LEN; i++) {
            GbtStagePatternDomain gbtStagePattern = new GbtStagePatternDomain();
            gbtStagePattern.setStagePatternNumber(Integer.valueOf(ByteUtils.bytesUInt(stagePatternArrayResult[i][0])));
            gbtStagePattern.setStageNumber(Integer.valueOf(ByteUtils.bytesUInt(stagePatternArrayResult[i][1])));
            byte[] allowPhase = {stagePatternArrayResult[i][2], stagePatternArrayResult[i][3], stagePatternArrayResult[i][4], stagePatternArrayResult[i][5]};
            gbtStagePattern.setAllowPhase(ByteUtils.byteToInt(allowPhase));
            gbtStagePattern.setGreenTime(ByteUtils.bytesUInt(stagePatternArrayResult[i][6]));
            gbtStagePattern.setYellowTime(ByteUtils.bytesUInt(stagePatternArrayResult[i][7]));
            gbtStagePattern.setRedTime(ByteUtils.bytesUInt(stagePatternArrayResult[i][8]));
            gbtStagePattern.setOption(ByteUtils.bytesUInt(stagePatternArrayResult[i][9]));
            gbtStagePattern.setPhaseList(BinaryUtils.intConvertToIntList(gbtStagePattern.getAllowPhase()));
            gbtStagePatterns.add(gbtStagePattern);
        }
        return gbtStagePatterns;
    }

    /**
     * 阶段
     * 系统向信号机发出阶段数据请求，信号机返回byte[]数组
     * 通过此方法 ，解析出对象列表
     * 一个使用 netty 或mina 进行UDP请求。
     *
     * @param bytes
     * @return
     */
    public static List<GbtStagePatternDomain> byte2StagePattern(byte[] bytes) {
        try {
            List<GbtStagePatternDomain> gbtStagePatterns = new ArrayList<GbtStagePatternDomain>();
            int len = bytes[Gbt209992007.STAGE_RESULT_THIS_OFFSET_LEN];
            int oneArrayLen = bytes.length - Gbt209992007.STAGE_RESULT_START_OFFSET_POSITION;
            int allLen = oneArrayLen / Gbt209992007.STAGEPATTERN_BYTE_SIZE;
            byte[] objectArray = new byte[oneArrayLen];
            System.arraycopy(bytes, Gbt209992007.STAGE_RESULT_START_OFFSET_POSITION, objectArray, 0, oneArrayLen);
            byte[][] stagePatternArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, allLen, Gbt209992007.STAGEPATTERN_BYTE_SIZE);
            for (int i = 0; i < len; i++) {
                GbtStagePatternDomain gbtStagePattern = new GbtStagePatternDomain();
                gbtStagePattern.setStagePatternNumber(Integer.valueOf(ByteUtils.bytesUInt(stagePatternArrayResult[i][0])));
                gbtStagePattern.setStageNumber(Integer.valueOf(ByteUtils.bytesUInt(stagePatternArrayResult[i][1])));
                byte[] allowPhase = {stagePatternArrayResult[i][2], stagePatternArrayResult[i][3], stagePatternArrayResult[i][4], stagePatternArrayResult[i][5]};
                gbtStagePattern.setAllowPhase(ByteUtils.byteToInt(allowPhase));
                gbtStagePattern.setGreenTime(ByteUtils.bytesUInt(stagePatternArrayResult[i][6]));
                gbtStagePattern.setYellowTime(ByteUtils.bytesUInt(stagePatternArrayResult[i][7]));
                gbtStagePattern.setRedTime(ByteUtils.bytesUInt(stagePatternArrayResult[i][8]));
                gbtStagePattern.setOption(ByteUtils.bytesUInt(stagePatternArrayResult[i][9]));
                gbtStagePattern.setPhaseList(BinaryUtils.intConvertToIntList(gbtStagePattern.getAllowPhase()));
                gbtStagePatterns.add(gbtStagePattern);
            }
            return gbtStagePatterns;
        } catch (Exception e) {
            LOG.error(e.getMessage());
            return null;
        }

    }


    /**
     * 设置信号机的配时方案，此方法适用于16相位的第一代信号机
     *
     * @param gbtStagePatterns
     * @return
     */
    public static byte[] stage2ByteWith16Phase(List<GbtStagePatternDomain> gbtStagePatterns) {

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_STAGEPATTERN_RESPONSE, (byte) gbtStagePatterns.size());
        hex = ArrayUtils.add(hex, (byte) (Gbt209992007.STAGE_RESULT_LEN));
        Iterator<GbtStagePatternDomain> gbtStagePatternIterator = gbtStagePatterns.iterator();
        while (gbtStagePatternIterator.hasNext()) {
            GbtStagePatternDomain gbtStagePattern = gbtStagePatternIterator.next();
            hex = ArrayUtils.add(hex, gbtStagePattern.getStagePatternNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getStageNumber().byteValue());
            hex = ArrayUtils.addAll(hex, ByteUtils.shortToByte(gbtStagePattern.getAllowPhase().shortValue()));
            hex = ArrayUtils.add(hex, gbtStagePattern.getGreenTime().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getYellowTime().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getRedTime().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getOption().byteValue());
        }

        return hex;

    }

    /**
     * 设置信号机的配时方案，此方法适用于第二代，第三代的信号机，32相位
     *
     * @param gbtStagePatterns
     * @return
     */
    public static byte[] stage2ByteWith32Phase(List<GbtStagePatternDomain> gbtStagePatterns) {
        byte[] hex = ArrayUtils.add(Gbt209992007.SET_STAGEPATTERN_RESPONSE, (byte) 0x00);
        int realSize = gbtStagePatterns.size();
        hex = ArrayUtils.add(hex, cn.com.aiton.common.utils.ByteUtils.intToByteOne(realSize));
        Iterator<GbtStagePatternDomain> gbtStagePatternIterator = gbtStagePatterns.iterator();
        while (gbtStagePatternIterator.hasNext()) {
            GbtStagePatternDomain gbtStagePattern = gbtStagePatternIterator.next();
            hex = ArrayUtils.add(hex, gbtStagePattern.getStagePatternNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getStageNumber().byteValue());
            hex = ArrayUtils.addAll(hex, ByteUtils.intToByteForHeighToLow(gbtStagePattern.getAllowPhase()));
            hex = ArrayUtils.add(hex, gbtStagePattern.getGreenTime().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getYellowTime().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getRedTime().byteValue());
            hex = ArrayUtils.add(hex, gbtStagePattern.getOption().byteValue());
        }

        return hex;
    }

    /**
     * 配置方案
     * 系统向信号机发出请求，信号机返回配置数据，byte[]数组
     * 通过此应运，将数组解析成对象列表
     *
     * @param bytes
     * @return
     */
    public static List<GbtPatternDomain> byte2Pattern(byte[] bytes) {
        List<GbtPatternDomain> gbtTimePatterns = new ArrayList<>();
        byte[] objectArray = new byte[bytes[3] * Gbt209992007.PATTERN_BYTE_SIZE];
        System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
        byte[][] timePatternArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.PATTERN_RESULT_LEN, Gbt209992007.PATTERN_BYTE_SIZE);
        for (int i = 0; i < bytes[3]; i++) {
            GbtPatternDomain gbtTimePattern = new GbtPatternDomain();
            gbtTimePattern.setPatternNumber(ByteUtils.bytesUInt(timePatternArrayResult[i][0]));
            gbtTimePattern.setCycleTime(ByteUtils.bytesUInt(timePatternArrayResult[i][1]));
            gbtTimePattern.setSoffset(ByteUtils.bytesUInt(timePatternArrayResult[i][2]));
            gbtTimePattern.setCoordinatePhase(ByteUtils.bytesUInt(timePatternArrayResult[i][3]));
            gbtTimePattern.setStagePatternNumber(ByteUtils.bytesUInt(timePatternArrayResult[i][4]));
            gbtTimePatterns.add(gbtTimePattern);
        }
        return gbtTimePatterns;
    }

    /**
     * 设置配时方案，将在配时方案实体类的数据向信号机进行发送
     *
     * @param gbtTimePatterns
     * @return
     */
    public static byte[] pattern2Byte(List<GbtPatternDomain> gbtTimePatterns) {

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_PATTERN_RESPONSE, (byte) gbtTimePatterns.size());
        Iterator<GbtPatternDomain> gbtTimePatternIterator = gbtTimePatterns.iterator();
        while (gbtTimePatternIterator.hasNext()) {
            GbtPatternDomain gbtTimePattern = gbtTimePatternIterator.next();
            hex = ArrayUtils.add(hex, gbtTimePattern.getPatternNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getCycleTime().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getSoffset().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getCoordinatePhase().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getStagePatternNumber().byteValue());
        }
        return hex;

    }

    /**
     * 绿波带设置，可以通过此功能实现每个信号机的周期时长和相位差
     *
     * @param cycle  周期
     * @param offset 信号机的相位差
     * @return
     */
    public static byte[] pattern2Byte(List<GbtPatternDomain> models, int cycle, int offset) {
        for (GbtPatternDomain model :
                models) {
            model.setSoffset(offset);
            model.setCycleTime(cycle);
        }
        byte[] hex = ArrayUtils.add(Gbt209992007.SET_PATTERN_RESPONSE, (byte) models.size());
        Iterator<GbtPatternDomain> gbtTimePatternIterator = models.iterator();
        while (gbtTimePatternIterator.hasNext()) {
            GbtPatternDomain gbtTimePattern = gbtTimePatternIterator.next();
            hex = ArrayUtils.add(hex, gbtTimePattern.getPatternNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getCycleTime().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getSoffset().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getCoordinatePhase().byteValue());
            hex = ArrayUtils.add(hex, gbtTimePattern.getStagePatternNumber().byteValue());
        }
        return hex;

    }

    /**
     * 时基表
     * 系统请求信号机，信号机返回byte[]数组
     * 通过此方法，解析出对象列表
     *
     * @param bytes
     * @return
     */
    public static List<GbtPlanDomain> byte2Plan(byte[] bytes) {
        List<GbtPlanDomain> gbtTimeBases = new ArrayList<>();
        byte[] objectArray = new byte[bytes[Gbt209992007.PLAN_RESULT_SIZE] * Gbt209992007.PLAN_BYTE_SIZE];
        System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
        byte[][] timeBaseArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.PLAN_RESULT_LEN, Gbt209992007.PLAN_BYTE_SIZE);
        for (int i = 0; i < bytes[Gbt209992007.PLAN_RESULT_SIZE]; i++) {
            GbtPlanDomain gbtTimeBase = new GbtPlanDomain();
            gbtTimeBase.setPlanNumber(ByteUtils.bytesUInt(timeBaseArrayResult[i][0]));
            byte[] flag = new byte[]{timeBaseArrayResult[i][1], timeBaseArrayResult[i][2]};
            Short sh = ByteUtils.byteToShort(flag);
            gbtTimeBase.setMonth(sh.intValue());
            gbtTimeBase.setWeek(ByteUtils.bytesUInt(timeBaseArrayResult[i][3]));
            byte[] dayFlag = new byte[]{timeBaseArrayResult[i][4], timeBaseArrayResult[i][5], timeBaseArrayResult[i][6], timeBaseArrayResult[i][7]};
            gbtTimeBase.setDay(ByteUtils.byteToInt(dayFlag));
            gbtTimeBase.setScheduleNumber(ByteUtils.bytesUInt(timeBaseArrayResult[i][8]));
            /**转换成编号数组*/
            Integer m = gbtTimeBase.getMonth();
            m = Integer.valueOf(m >> 1);
            gbtTimeBase.setMonthList(JsonToPlanUtil.monthConvertToIntList(m));
            for (int j = 0; j < gbtTimeBase.getMonthList().size(); j++) {
                Integer ii = gbtTimeBase.getMonthList().get(j);
                if (ii > 12) gbtTimeBase.getMonthList().remove(j);
            }
            gbtTimeBase.setWeekList(JsonToPlanUtil.weekConvertToIntList(gbtTimeBase.getWeek() >> 1));
            gbtTimeBase.setDayList(JsonToPlanUtil.dayConvertToIntList(gbtTimeBase.getDay() >> 1));
            /** BY HYQ */
            gbtTimeBases.add(gbtTimeBase);
        }
        return gbtTimeBases;
    }

    /**
     * 设置时基数据到信号机
     * 通过月历
     *
     * @param gbtTimeBaseList
     * @return
     */
    public static byte[] plan2ByteWithMonth(List<GbtPlanDomain> gbtTimeBaseList) {

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_PLAN_RESPONSE, (byte) gbtTimeBaseList.size());
        Iterator<GbtPlanDomain> gbtTimeBaseIterator = gbtTimeBaseList.iterator();
        while (gbtTimeBaseIterator.hasNext()) {
            GbtPlanDomain gbtTimeBase = gbtTimeBaseIterator.next();
            byte timeBaseId = gbtTimeBase.getPlanNumber().byteValue();
            byte[] monthFlagTemp = ByteUtils.intToByte(gbtTimeBase.getMonth());
            byte[] monthFlag = new byte[2];
            monthFlag[0] = monthFlagTemp[0];
            monthFlag[1] = monthFlagTemp[1];
            byte weekFlag = gbtTimeBase.getWeek().byteValue();
            byte[] dayFlag = ByteUtils.intToByte(gbtTimeBase.getDay());
            byte scheduleId = gbtTimeBase.getScheduleNumber().byteValue();
            hex = ArrayUtils.add(hex, timeBaseId);
            hex = ArrayUtils.add(hex, monthFlag[1]);
            hex = ArrayUtils.add(hex, monthFlag[0]);
            //      顺序要反着放 才能跟接收的结构相对应
            //      接收的顺序是  ID字节  +   月字节高位   + 月字节低位  +  周字节   。。。。。
            //      所以发送的顺序也必须这样：
            //                  ID字节  +   月字节高位   + 月字节低位  +  周字节
            //      老代码有错误！！！已更正
            //      ArrayUtils.addAll([1,2],[3,4]) ==>  [1,2,3,4]
            hex = ArrayUtils.add(hex, weekFlag);
            hex = ArrayUtils.add(hex, dayFlag[3]);
            hex = ArrayUtils.add(hex, dayFlag[2]);
            hex = ArrayUtils.add(hex, dayFlag[1]);
            hex = ArrayUtils.add(hex, dayFlag[0]);
            hex = ArrayUtils.add(hex, scheduleId);
        }

        return hex;
    }

    /**
     * 设置时基数据到信号机
     * 通过周模式
     * ====>周末
     *
     * @param gbtTimeBases
     * @return
     */
    public static byte[] plan2ByteWithWeek(List<GbtPlanDomain> gbtTimeBases) {

        byte[] hex = ArrayUtils.add(Gbt209992007.SET_PLAN_RESPONSE, (byte) gbtTimeBases.size());
        Iterator<GbtPlanDomain> gbtTimeBaseIterator = gbtTimeBases.iterator();
        while (gbtTimeBaseIterator.hasNext()) {
            GbtPlanDomain gbtTimeBase = gbtTimeBaseIterator.next();
            byte timeBaseId = gbtTimeBase.getPlanNumber().byteValue();
            byte[] monthFlagTemp = ByteUtils.intToByte(gbtTimeBase.getMonth());
            byte[] monthFlag = new byte[2];
            monthFlag[0] = monthFlagTemp[0];
            monthFlag[1] = monthFlagTemp[1];
            byte weekFlag = gbtTimeBase.getWeek().byteValue();
            byte[] dayFlag = ByteUtils.intToByte(gbtTimeBase.getDay());
            byte scheduleId = gbtTimeBase.getScheduleNumber().byteValue();
            hex = ArrayUtils.add(hex, timeBaseId);
            hex = ArrayUtils.addAll(hex, monthFlag);
            hex = ArrayUtils.add(hex, weekFlag);
            hex = ArrayUtils.addAll(hex, dayFlag);
            hex = ArrayUtils.add(hex, scheduleId);
        }

        return hex;
    }

    /**
     * 从信号机读取时基数据
     * 将字节数组字符串
     *
     * @param bytes
     * @return
     */
    public static String getPlanByteString(byte[] bytes) {

        String str = ByteUtils.bytesToHexString(bytes);
        return str;
    }

    /**
     * 向信号机设置时基数据
     * 以字符串的形式，但数据与字节是一样
     *
     * @param str
     * @return
     */
    public static byte[] setPlanByteString(String str) {

        byte[] hex = ByteUtils.hexStringToByte(str);

        return hex;

    }

    /**
     * 取得16位信号机的绿冲突数据
     */
    public static List<GbtCollisionDomain> byte2CollisionBy16Phase(byte[] bytes) {
        List<GbtCollisionDomain> gbtCollisions = new ArrayList<>();
        try {
            byte[] objectArray = new byte[bytes[3] * Gbt209992007.GBT20999_COLLISION_BYTE_SIZE];
            System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
            byte[][] collisionArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.COLLISION_RESULT_LENGTH, Gbt209992007.GBT20999_COLLISION_BYTE_SIZE);
            for (int i = 0; i < bytes[3]; i++) {
                GbtCollisionDomain gbtCollision = new GbtCollisionDomain();
                int a = collisionArrayResult[i][0];
                gbtCollision.setPhaseNumber(a);
                byte[] flag = new byte[]{collisionArrayResult[i][1], collisionArrayResult[i][2]};
                gbtCollision.setFlag(ByteUtils.byteToInt(flag));
                gbtCollisions.add(gbtCollision);
            }
            return gbtCollisions;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 取得32相位信号机的绿冲突数据
     *
     * @param bytes
     */
    public static List<GbtCollisionDomain> byte2CollisionBy32Phase(byte[] bytes) {
        List<GbtCollisionDomain> gbtCollisions = new ArrayList<>();
        try {
            byte[] objectArray = new byte[bytes[3] * Gbt209992007.COLLISION_BYTE_SIZE];
            System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
            byte[][] collisionArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.COLLISION_RESULT_LENGTH, Gbt209992007.COLLISION_BYTE_SIZE);
            for (int i = 0; i < bytes[3]; i++) {
                GbtCollisionDomain gbtCollision = new GbtCollisionDomain();
                gbtCollision.setPhaseNumber(ByteUtils.bytesUInt(collisionArrayResult[i][0]));
                byte[] flag = new byte[]{collisionArrayResult[i][1], collisionArrayResult[i][2], collisionArrayResult[i][3], collisionArrayResult[i][4]};
                gbtCollision.setFlag(ByteUtils.byteToInt(flag));
                gbtCollision.setCollisionPhases(BinaryUtils.intConvertToIntList(gbtCollision.getFlag()));
                gbtCollisions.add(gbtCollision);
            }
            return gbtCollisions;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 将配置的数据发送给某个信号机
     *
     * @param gbtCollisions
     */
    public static byte[] collision2Byte(List<GbtCollisionDomain> gbtCollisions) {
        try {
            byte[] hex = ArrayUtils.add(Gbt209992007.SET_COLLISION_RESPONSE, (byte) gbtCollisions.size());
            Iterator<GbtCollisionDomain> gbtCollisionIterator = gbtCollisions.iterator();
            while (gbtCollisionIterator.hasNext()) {
                GbtCollisionDomain gbtCollision = gbtCollisionIterator.next();
                byte[] flag = ByteUtils.intToByteForHeighToLow(gbtCollision.getFlag());

                byte[] phaseId = {gbtCollision.getPhaseNumber().byteValue()};
                byte[] objectArray = ArrayUtils.addAll(phaseId, flag);
                hex = ArrayUtils.addAll(hex, objectArray);
            }
            return hex;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 取得所有检测器的配置数据
     *
     * @param bytes
     * @return
     */
    public static List<GbtDetectorDomain> byte2Detector(byte[] bytes) {
        List<GbtDetectorDomain> gbtDetectors = new ArrayList<>();
        try {

            byte[] objectArray = new byte[bytes[3] * Gbt209992007.DETECTOR_BYTE_SIZE];
            System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);
            byte[][] detectorArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, Gbt209992007.DETECTOR_RESULT_LEN, Gbt209992007.DETECTOR_BYTE_SIZE);
            for (int i = 0; i < bytes[3]; i++) {
                GbtDetectorDomain gbtDetector = new GbtDetectorDomain();
                gbtDetector.setDetectorNumber(ByteUtils.bytesUInt(detectorArrayResult[i][0]));
                gbtDetector.setPhaseNumber(ByteUtils.bytesUInt(detectorArrayResult[i][1]));
                gbtDetector.setDetectorType(ByteUtils.bytesUInt(detectorArrayResult[i][2]));
                gbtDetector.setDirec(ByteUtils.bytesUInt(detectorArrayResult[i][3]));
                gbtDetector.setRequestEffectTime(ByteUtils.bytesUInt(detectorArrayResult[i][4]));
                gbtDetector.setDetectorOption(ByteUtils.bytesUInt(detectorArrayResult[i][5]));
                gbtDetector.setSaturationVolume(((detectorArrayResult[i][6] << 8) + detectorArrayResult[i][7]));
                gbtDetector.setSaturationOccupancy(ByteUtils.bytesUInt(detectorArrayResult[i][8]));
                gbtDetectors.add(gbtDetector);
            }
            return gbtDetectors;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 设置所有检测器配置数据
     *
     * @param gbtDetectors
     * @return
     */
    public static byte[] detector2Byte(List<GbtDetectorDomain> gbtDetectors) {
        try {
            byte[] hex = ArrayUtils.add(Gbt209992007.SET_DETECTOR_RESPONSE, (byte) gbtDetectors.size());
            Iterator<GbtDetectorDomain> gbtDetectorIterator = gbtDetectors.iterator();
            while (gbtDetectorIterator.hasNext()) {
                GbtDetectorDomain gbtDetector = gbtDetectorIterator.next();
                byte[] saturationVolume = ByteUtils.intToByteArrayTwoBit(gbtDetector.getSaturationVolume());
                byte[] objectArray = {gbtDetector.getDetectorNumber().byteValue(), gbtDetector.getPhaseNumber().byteValue(), gbtDetector.getDetectorType().byteValue(), gbtDetector.getDirec().byteValue(), gbtDetector.getRequestEffectTime().byteValue(), gbtDetector.getDetectorOption().byteValue(), saturationVolume[1], saturationVolume[0], gbtDetector.getSaturationOccupancy().byteValue()};
                hex = ArrayUtils.addAll(hex, objectArray);
            }
            return hex;
        } catch (Exception ex) {
            return null;
        }
    }
    /**
     * 从设备中取得日志数据信息
     * 目前安卓系统使用此方法 ，采用netty 框架
     * @param bytes
     * @return
     */
    public static List<GbtEventLogDomain> byte2EventLog(int len,byte[] bytes) {
        List<GbtEventLogDomain> gbtEventLogs = new ArrayList<>();
        byte[][] eventLogResult = ByteUtils.oneArrayToTwoArray(bytes, len, Gbt209992007.EVENT_LOG_BYTE_SIZE);
        GbtEventLogDomain gbtEventLog = null;
        for (int i = 0; i < len; i++) {
            gbtEventLog = new GbtEventLogDomain();
            gbtEventLog.setEventLogNumber(Integer.valueOf(ByteUtils.bytesUInt(eventLogResult[i][0])));
            gbtEventLog.setEventLogType(ByteUtils.bytesUInt(eventLogResult[i][1]));
            gbtEventLog.setHappenTime((long) (eventLogResult[i][2] << 24) + (eventLogResult[i][3] << 16) + (eventLogResult[i][4] << 8) + (eventLogResult[i][5]));
            gbtEventLog.setEventLogValue((long) (eventLogResult[i][6] << 24) + (eventLogResult[i][7] << 16) + (eventLogResult[i][8] << 8) + (eventLogResult[i][9]));
            gbtEventLog.setEventLogDesc(EventLogUtils.eventDescToString(gbtEventLog.getEventLogValue(), gbtEventLog.getEventLogType().byteValue()));
            gbtEventLog.setEventLogTime(DateTimeUtil.utcToLocalTimeString(gbtEventLog.getHappenTime()));
            gbtEventLogs.add(gbtEventLog);
        }
        return gbtEventLogs;

    }

    /**
     * 从设备中取得日志数据信息
     *
     * @param bytes
     * @return
     */
    public static List<GbtEventLogDomain> byte2EventLog(byte[] bytes) {
        List<GbtEventLogDomain> gbtEventLogs = new ArrayList<>();
        int len = bytes.length -8;
        int resultLen = len /10;
        byte[] objectArray = new byte[len];
        System.arraycopy(bytes, 7, objectArray, 0, len);
        byte[][] eventLogResult = ByteUtils.oneArrayToTwoArray(objectArray, resultLen, Gbt209992007.EVENT_LOG_BYTE_SIZE);
        GbtEventLogDomain gbtEventLog = null;
        for (int i = 0; i < resultLen; i++) {
            gbtEventLog = new GbtEventLogDomain();
            gbtEventLog.setEventLogNumber(Integer.valueOf(ByteUtils.bytesUInt(eventLogResult[i][0])));
            gbtEventLog.setEventLogType(ByteUtils.bytesUInt(eventLogResult[i][1]));
            gbtEventLog.setHappenTime((long) (eventLogResult[i][2] << 24) + (eventLogResult[i][3] << 16) + (eventLogResult[i][4] << 8) + (eventLogResult[i][5]));
            gbtEventLog.setEventLogValue((long) (eventLogResult[i][6] << 24) + (eventLogResult[i][7] << 16) + (eventLogResult[i][8] << 8) + (eventLogResult[i][9]));
            gbtEventLog.setEventLogDesc(EventLogUtils.eventDescToString(gbtEventLog.getEventLogValue(), gbtEventLog.getEventLogType().byteValue()));
            gbtEventLog.setEventLogTime(DateTimeUtil.utcToLocalTimeString(gbtEventLog.getHappenTime()));
            gbtEventLogs.add(gbtEventLog);
        }
        return gbtEventLogs;

    }

    /**
     * 根据时间取得日志数据，
     *
     * @param bytes
     * @param date  转换成long 进行比较
     * @return
     */
    public static List<GbtEventLogDomain> byte2EventLogWithTime(byte[] bytes, Date date) {
        List<GbtEventLogDomain> gbtEventLogs = new ArrayList<>();

        int unsignedInt = ByteUtils.bytesUInt(bytes[6]);
        byte[] objectArray = new byte[unsignedInt * Gbt209992007.EVENT_LOG_BYTE_SIZE];
        System.arraycopy(bytes, 7, objectArray, 0, objectArray.length);
        byte[][] eventLogResult = ByteUtils.oneArrayToTwoArray(objectArray, unsignedInt, Gbt209992007.EVENT_LOG_BYTE_SIZE);
        GbtEventLogDomain gbtEventLog = null;
        for (int i = 0; i < unsignedInt; i++) {
            Long happenTime = (long) (eventLogResult[i][2] << 24) + (eventLogResult[i][3] << 16) + (eventLogResult[i][4] << 8) + (eventLogResult[i][5]);
            if (happenTime != date.getTime()) {
                continue;
            }
            gbtEventLog = new GbtEventLogDomain();
            gbtEventLog.setEventLogNumber(ByteUtils.bytesUInt(eventLogResult[i][0]));
            gbtEventLog.setEventLogType(ByteUtils.bytesUInt(eventLogResult[i][1]));
            gbtEventLog.setHappenTime(happenTime);
            gbtEventLog.setEventLogValue((long) (eventLogResult[i][6] << 24) + (eventLogResult[i][7] << 16) + (eventLogResult[i][8] << 8) + (eventLogResult[i][9]));
            gbtEventLog.setEventLogDesc(EventLogUtils.eventDescToString(gbtEventLog.getEventLogValue(), gbtEventLog.getEventLogType().byteValue()));
            gbtEventLog.setEventLogTime(DateTimeUtil.utcToLocalTimeString(gbtEventLog.getHappenTime()));
            gbtEventLogs.add(gbtEventLog);
        }

        return gbtEventLogs;

    }

    /**
     * 根据日志类型，取得日志
     *
     * @param bytes
     * @param type  类型
     * @return
     */
    public static List<GbtEventLogDomain> byte2EventLogWithEventType(byte[] bytes, byte type) {
        List<GbtEventLogDomain> gbtEventLogs = new ArrayList<>();
        int unsignedInt = ByteUtils.bytesUInt(bytes[6]);
        byte[] objectArray = new byte[unsignedInt * Gbt209992007.EVENT_LOG_BYTE_SIZE];
        System.arraycopy(bytes, 7, objectArray, 0, objectArray.length);
        byte[][] eventLogResult = ByteUtils.oneArrayToTwoArray(objectArray, unsignedInt, Gbt209992007.EVENT_LOG_BYTE_SIZE);
        GbtEventLogDomain gbtEventLog = null;
        for (int i = 0; i < unsignedInt; i++) {
            Byte eventType = eventLogResult[i][1];
            if (eventType != type) {
                continue;
            }
            gbtEventLog = new GbtEventLogDomain();
            gbtEventLog.setEventLogNumber(ByteUtils.bytesUInt(eventLogResult[i][0]));
            gbtEventLog.setEventLogType(eventType.intValue());
            gbtEventLog.setHappenTime((long) (eventLogResult[i][2] << 24) + (eventLogResult[i][3] << 16) + (eventLogResult[i][4] << 8) + (eventLogResult[i][5]));
            gbtEventLog.setEventLogValue((long) (eventLogResult[i][6] << 24) + (eventLogResult[i][7] << 16) + (eventLogResult[i][8] << 8) + (eventLogResult[i][9]));
            gbtEventLog.setEventLogDesc(EventLogUtils.eventDescToString(gbtEventLog.getEventLogValue(), gbtEventLog.getEventLogType().byteValue()));
            gbtEventLog.setEventLogTime(DateTimeUtil.utcToLocalTimeString(gbtEventLog.getHappenTime()));
            gbtEventLogs.add(gbtEventLog);
        }
        return gbtEventLogs;

    }

    /**
     * 根据开始时间和结束时间，取得日志数据
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<GbtEventLogDomain> byte2EventLogWithStartAndEndTime(byte[] bytes, Date startTime, Date endTime) {
        ServiceResult<List<GbtEventLogDomain>> result = new ServiceResult<>();
        List<GbtEventLogDomain> gbtEventLogs = new ArrayList<>();

        int unsignedInt = ByteUtils.bytesUInt(bytes[6]);
        byte[] objectArray = new byte[unsignedInt * Gbt209992007.EVENT_LOG_BYTE_SIZE];
        System.arraycopy(bytes, 7, objectArray, 0, objectArray.length);
        byte[][] eventLogResult = ByteUtils.oneArrayToTwoArray(objectArray, unsignedInt, Gbt209992007.EVENT_LOG_BYTE_SIZE);
        GbtEventLogDomain gbtEventLog = null;
        for (int i = 0; i < unsignedInt; i++) {
            Long happenTime = (long) (eventLogResult[i][2] << 24) + (eventLogResult[i][3] << 16) + (eventLogResult[i][4] << 8) + (eventLogResult[i][5]);
            if (happenTime < startTime.getTime() || happenTime > endTime.getTime()) {
                continue;
            }
            gbtEventLog = new GbtEventLogDomain();
            gbtEventLog.setEventLogNumber(ByteUtils.bytesUInt(eventLogResult[i][0]));
            gbtEventLog.setEventLogType(ByteUtils.bytesUInt(eventLogResult[i][1]));
            gbtEventLog.setHappenTime(happenTime);
            gbtEventLog.setEventLogValue((long) (eventLogResult[i][6] << 24) + (eventLogResult[i][7] << 16) + (eventLogResult[i][8] << 8) + (eventLogResult[i][9]));
            gbtEventLog.setEventLogDesc(EventLogUtils.eventDescToString(gbtEventLog.getEventLogValue(), gbtEventLog.getEventLogType().byteValue()));
            gbtEventLog.setEventLogTime(DateTimeUtil.utcToLocalTimeString(gbtEventLog.getHappenTime()));
            gbtEventLogs.add(gbtEventLog);
        }
        return gbtEventLogs;

    }


    /**
     * 取得某个信号的厂家模块信息
     *
     * @param bytes
     * @return
     */
    public static List<GbtModuleDomain> byte2Module(byte[] bytes) throws Exception {
        List<GbtModuleDomain> gbtModules = new ArrayList<>();
        List<byte[]> everyByteArray = new ArrayList<byte[]>();

        //去除协议头
        byte[] objectArray = new byte[bytes.length - 4];
        System.arraycopy(bytes, 4, objectArray, 0, objectArray.length);

        int count = 0;
        int modules = bytes[3];
        //一条记录的长度
        for (int i = 0; i < modules; i++) {
            int idcount = 1;
            int devNode = objectArray[1 + count];
            //这里加1是因为有一个字节 的设备节点长度。并不是数据
            int company = objectArray[devNode + 1 + count + idcount];
            //这里加2 = 1（devNode长度字节）+ 1（company长度字节）。并不是数据
            int model = objectArray[devNode + 2 + company + count + idcount];
            //这里加3 = 1（devNode长度字节）+ 1（company长度字节）+ 1（model长度字节）。并不是数据
            int version = objectArray[devNode + 3 + model + company + count + idcount];
            int typeCount = 1;
            //最后 加上4， 是因为，有四个字段的字节长度属性，并不是真正的数据
            int all = idcount + devNode + company + model + version + typeCount + 4;
            byte[] oneSetByteArray = new byte[all];
            System.arraycopy(objectArray, count, oneSetByteArray, 0, all);
            everyByteArray.add(oneSetByteArray);
            count = count + all;
        }

        Iterator it = everyByteArray.iterator();
        while (it.hasNext()) {
            byte[] bar = (byte[]) it.next();
            int idCount = 1;
            int devNodeCount = bar[1];
            int companyCount = bar[devNodeCount + 1 + idCount];
            int modelCount = bar[devNodeCount + 2 + companyCount + idCount];
            int versionCount = bar[devNodeCount + 3 + companyCount + modelCount + idCount];
            //取得节点
            byte[] byteDevNode = new byte[devNodeCount];
            idCount += 1;
            for (int j = 0; j < devNodeCount; j++) {
                byteDevNode[j] = bar[j + idCount];
            }
            String sDevNode = ByteUtils.byteArrayToStringByISO(byteDevNode);
            //取得厂家数据
            byte[] byteCompany = new byte[companyCount];
            devNodeCount += 1;
            for (int k = 0; k < companyCount; k++) {
                byteCompany[k] = bar[idCount + devNodeCount + k];
            }
            String sCompany = ByteUtils.byteArrayToStringByISO(byteCompany);
            //取得模式
            byte[] byteModel = new byte[modelCount];
            companyCount += 1;
            for (int l = 0; l < modelCount; l++) {
                byteModel[l] = bar[idCount + devNodeCount + companyCount + l];
            }
            String sModel = ByteUtils.byteArrayToStringByISO(byteModel);
            //取得 版本号
            byte[] byteVersion = new byte[versionCount];
            modelCount += 1;
            for (int u = 0; u < versionCount; u++) {
                byteVersion[u] = bar[idCount + devNodeCount + modelCount + companyCount + u];
            }
            String sVersion = ByteUtils.byteArrayToStringByISO(byteVersion);
            GbtModuleDomain gbtModule = new GbtModuleDomain();
            gbtModule.setModuleId(new Integer(bar[0]));
            gbtModule.setDevNode(sDevNode);
            gbtModule.setCompany(sCompany);
            gbtModule.setModel(sModel);
            gbtModule.setVersion(sVersion);
            gbtModule.setType(Integer.valueOf(bar[idCount + devNodeCount + modelCount + companyCount + versionCount]));
            gbtModules.add(gbtModule);
        }

        return gbtModules;

    }

    /**
     * by Me   得到模块的状态
     *
     * @param bytes
     * @return
     */
    public static byte[] getModuleState(byte[] bytes) {
        //TODO  这里要对模块的状态数据进行发行，还要创建Doamin类，
        return null;
    }


    /**
     * 设置信号机的时段表数据
     *
     * @param byteString
     * @return
     */
    public static byte[] setScheduleByteString(String byteString) {

        byte[] hex = ByteUtils.hexStringToByte(byteString);

        return hex;

    }

    /**
     * 得到信号机的时段表的数据，为字符串数组
     *
     * @param bytes
     * @return
     */
    public static String byte2ScheduleString(byte[] bytes) {

        String str = ByteUtils.bytesToHexString(bytes);

        return str;

    }

    /**
     * 取得信号机的时段表数据，返回的参数为时段对模型的集合
     * int len = bytes[Gbt209992007.STAGE_RESULT_THIS_OFFSET_LEN];
     * byte[] objectArray = new byte[len * Gbt209992007.STAGEPATTERN_BYTE_SIZE];
     * System.arraycopy(bytes, Gbt209992007.STAGE_RESULT_START_OFFSET_POSITION, objectArray, 0, objectArray.length);
     * byte[][] stagePatternArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, len, Gbt209992007.STAGEPATTERN_BYTE_SIZE);
     * for (int i = 0; i < len; i++) {
     *
     * @param bytes
     * @return
     */
    public static List<GbtScheduleDomain> byte2Schedule(byte[] bytes) {

        List<GbtScheduleDomain> gbtSchedules = new ArrayList<>();
        //取得记录数
        int len = bytes[Gbt209992007.SCHEDULE_RESULT_RESPONSE_COUNT_BIT_4];
        byte[] objectArray = new byte[len * Gbt209992007.SCHEDULE_BYTE_SIZE];
        System.arraycopy(bytes, Gbt209992007.SCHEDULE_RESULT_RESPONSE_BODY_START_BIT_5, objectArray, 0, objectArray.length);
        byte[][] scheduleArrayResult = ByteUtils.oneArrayToTwoArray(objectArray, len, Gbt209992007.SCHEDULE_BYTE_SIZE);
        for (int i = 0; i < len; i++) {
            GbtScheduleDomain gbtSchedule = new GbtScheduleDomain();
            gbtSchedule.setScheduleNumber(ByteUtils.bytesUInt(scheduleArrayResult[i][0]));
            gbtSchedule.setEventNumber(ByteUtils.bytesUInt(scheduleArrayResult[i][1]));
            gbtSchedule.setBeginHour(ByteUtils.bytesUInt(scheduleArrayResult[i][2]));
            gbtSchedule.setBeginMinute(ByteUtils.bytesUInt(scheduleArrayResult[i][3]));
            gbtSchedule.setControlMode(ByteUtils.bytesUInt(scheduleArrayResult[i][4]));
            gbtSchedule.setPatternNumber(ByteUtils.bytesUInt(scheduleArrayResult[i][5]));
            gbtSchedule.setAuxOut(ByteUtils.bytesUInt(scheduleArrayResult[i][6]));
            gbtSchedule.setSpecialOut(ByteUtils.bytesUInt(scheduleArrayResult[i][7]));
            gbtSchedules.add(gbtSchedule);
        }

        return gbtSchedules;

    }

    /**
     * 设置时段表的参数。传入参数为时段表的模型的集合
     *
     * @param gbtSchedules
     * @return
     */
    public static byte[] schedule2Byte(List<GbtScheduleDomain> gbtSchedules) {


        byte[] hex = ArrayUtils.add(Gbt209992007.SET_SCHEDULE_RESPONSE, (byte) 0x10);
        hex = ArrayUtils.add(hex, (byte) 0x30);
        Iterator<GbtScheduleDomain> gbtScheduleIterator = gbtSchedules.iterator();
        while (gbtScheduleIterator.hasNext()) {
            GbtScheduleDomain gbtSchedule = gbtScheduleIterator.next();
            hex = ArrayUtils.add(hex, gbtSchedule.getScheduleNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtSchedule.getEventNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtSchedule.getBeginHour().byteValue());
            hex = ArrayUtils.add(hex, gbtSchedule.getBeginMinute().byteValue());
            hex = ArrayUtils.add(hex, gbtSchedule.getControlMode().byteValue());
            hex = ArrayUtils.add(hex, gbtSchedule.getPatternNumber().byteValue());
            hex = ArrayUtils.add(hex, gbtSchedule.getAuxOut().byteValue());
            hex = ArrayUtils.add(hex, gbtSchedule.getSpecialOut().byteValue());
        }

        return hex;


    }
}
